﻿using System;
using System.Collections.Generic;
using System.Net.Mail;
using Dexter.Domain.Model;
using Dexter.Domain.Results;
using Dexter.Logger.Contracts;
using Dexter.Repository;

namespace Dexter.Services.Implementation {
	public class ContactService : IContactService {
		readonly IConfigurationService configurationService;
		readonly IEmailService emailService;
		readonly IEmailTemplateService emailTemplateService;
		readonly ILogger logger;
		readonly IInboxRepository inboxRepository;

		/// <summary>
		/// Initializes a new instance of the <see cref="ContactService"/> class.
		/// </summary>
		/// <param name="configurationService">The configuration service.</param>
		/// <param name="emailService">The email service.</param>
		/// <param name="emailTemplateService">The email template service.</param>
		/// <param name="logger">The logger.</param>
		/// <param name="inboxRepository">The inbox repository.</param>
		public ContactService ( IConfigurationService configurationService , IEmailService emailService , IEmailTemplateService emailTemplateService , ILogger logger , IInboxRepository inboxRepository ) {
			this.configurationService = configurationService;
			this.inboxRepository = inboxRepository;
			this.emailService = emailService;
			this.emailTemplateService = emailTemplateService;
			this.logger = logger;
		}

		public void SendMessage ( InboxMessage message ) {
			inboxRepository.Save ( message );
			emailService.Queue ( GetMailMessage ( message ) );
		}

		///<summary>
		///	Return a list of <see cref="InboxMessage"/> sorted by creation date.
		///</summary>
		///<param name = "pageIndex">Index of the page (0 based).</param>
		///<param name = "pageSize">The number of items to retrieve.</param>
		///<returns>An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.</returns>
		///<exception cref="ArgumentOutOfRangeException"> If <paramref name="pageIndex"/> is lesser than 0.</exception>
		///<exception cref="ArgumentOutOfRangeException"> If <paramref name="pageSize"/> is lesser than 1.</exception>
		public IPagedResult <InboxMessage> GetList ( int pageIndex , int pageSize ) {
			return GetList ( pageIndex , pageSize , false );
		}

		///<summary>
		///	Return a list of <see cref="InboxMessage"/> sorted by creation date.
		///</summary>
		///<param name = "pageIndex">Index of the page (0 based).</param>
		///<param name = "pageSize">The number of items to retrieve.</param>
		/// <param name = "enableTracking">if set to <c>true</c> the tracking system of the return object will be enable.</param>
		///<returns>An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.</returns>
		///<exception cref="ArgumentOutOfRangeException"> If <paramref name="pageIndex"/> is lesser than 0.</exception>
		///<exception cref="ArgumentOutOfRangeException"> If <paramref name="pageSize"/> is lesser than 1.</exception>
		public IPagedResult <InboxMessage> GetList ( int pageIndex , int pageSize , bool enableTracking ) {
			return inboxRepository.GetList ( pageIndex , pageSize , enableTracking );
		}

		EmailMessage GetMailMessage ( InboxMessage message ) {
			const string TEMPLATE_NAME = "dexter.contact.newcontact";

			var configuration = configurationService.Configuration;

			var template = emailTemplateService.GetTemplate ( TEMPLATE_NAME );

			if (template == null) {
				logger.WarnFormat ( "Template '{0}' not found.", TEMPLATE_NAME );
				return null;
			}

			IDictionary<string, string> values = new Dictionary<string, string> {
				{"ContactName" , message.Name} ,
				{"ContactEmail" , message.Email} ,
				{"ContactSubject" , message.Subject} ,
				{"ContactDate" , message.MessageDate.ToShortDateString (  )} ,
				{"ContactMessage" , message.Message}
			};

			string subject = template.GetFormatedSubject ( values );
			string body = template.GetFormatedBody ( values );

			var email = new MailAddress ( configuration.NotificationConfiguration.NotificationEmailAddress , configuration.NotificationConfiguration.NotificationEmailAddress );

			var resultEmail = EmailMessage.CreateNewEmailMessage ( configuration.NotificationConfiguration.SenderEmail, email, subject, body );

			return resultEmail;
		}
	}
}
